﻿using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace Custom.Infrastructure
{
    public class DbContext<T> where T : class, new()
    {
        public SqlSugarClient Db;
        public DbContext()
        {
            Db = new SqlSugarClient(new ConnectionConfig()
            {
                ConnectionString = DBConnectionConfig.ConnectionString,
                DbType = DbType.Sqlite,
                InitKeyType = InitKeyType.SystemTable,
                IsAutoCloseConnection = true
            });
        }

        public SimpleClient<T> CurrentDb { get { return new SimpleClient<T>(Db); } }//用来操作当前表的数据

        /// <summary>
        /// 根据主键查询
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual T Get(dynamic id)
        {
            return Db.Queryable<T>().InSingle(id);
        }

        /// <summary>
        /// 根据表达式查询
        /// </summary>
        /// <returns></returns>
        public virtual List<T> Get(Expression<Func<T, bool>> whereExpression)
        {
            return Db.Queryable<T>().Where(whereExpression).ToList();
        }

        /// <summary>
        /// 获取所有
        /// </summary>
        /// <returns></returns>
        public virtual List<T> GetAll()
        {
            return Db.Queryable<T>().ToList();
        }

        /// <summary>
        /// 根据表达式查询分页
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="pageIndex">页数</param>
        /// <param name="pageSize">每页条数</param>
        /// <param name="total">总数</param>
        /// <returns></returns>
        public virtual List<T> GetPage(Expression<Func<T, bool>> whereExpression, int pageIndex, int pageSize, ref int total)
        {
            return Db.Queryable<T>().Where(whereExpression).ToPageList(pageIndex, pageSize, ref total);
        }


        /// <summary>
        /// 根据表达式查询分页并排序
        /// </summary>
        /// <param name="whereExpression">it</param>
        /// <param name="pageModel"></param>
        /// <param name="orderByExpression">it=>it.id或者it=>new{it.id,it.name}</param>
        /// <param name="orderByType">OrderByType.Desc</param>
        /// <returns></returns>
        public virtual List<T> GetPage(Expression<Func<T, bool>> whereExpression, PageModel pageModel, ref int total, Expression<Func<T, object>> orderByExpression = null, OrderByType orderByType = OrderByType.Asc)
        {
            return Db.Queryable<T>().Where(whereExpression).OrderBy(orderByExpression, orderByType).ToPageList(pageModel.PageIndex, pageModel.PageSize, ref total);
        }

        /// <summary>
        /// 根据表达式查询分页并排序
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="total"></param>
        /// <param name="orderByExpression"></param>
        /// <param name="orderByType"></param>
        /// <returns></returns>
        public virtual List<T> GetPage(Expression<Func<T, bool>> whereExpression, int pageIndex, int pageSize, ref int total, Expression<Func<T, object>> orderByExpression = null, OrderByType orderByType = OrderByType.Asc)
        {
            return Db.Queryable<T>().Where(whereExpression).OrderBy(orderByExpression, orderByType).ToPageList(pageIndex, pageSize, ref total);
        }


        /// <summary>
        /// 插入
        /// </summary>
        /// <returns></returns>
        public virtual bool Insert(T t)
        {
            return CurrentDb.Insert(t);
        }

        /// <summary>
        /// 插入返回自增列
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public virtual int InsertReturnIdentity(T t)
        {
            return CurrentDb.InsertReturnIdentity(t);
        }


        /// <summary>
        /// 批量插入
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual bool Insert(List<T> entites)
        {
            return CurrentDb.InsertRange(entites);
        }


        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual bool Update(T t)
        {
            return CurrentDb.Update(t);
        }

        /// <summary>
        ///批量更新
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual bool Update(List<T> entites)
        {
            return CurrentDb.UpdateRange(entites);
        }

        /// <summary>
        /// 根据条件更新某个字段
        /// </summary>
        /// <param name="columns"></param>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        public virtual bool Update(Expression<Func<T, T>> columns, Expression<Func<T, bool>> whereExpression)
        {
            return CurrentDb.Update(columns, whereExpression);
        }

        /// <summary>
        /// 根据主键删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual bool Delete(dynamic id)
        {
            return CurrentDb.DeleteById(id);
        }


        /// <summary>
        /// 删除实体
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual bool Delete(T t)
        {
            return CurrentDb.Delete(t);
        }

        /// <summary>
        /// 根据条件删除
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        public virtual bool Delete(Expression<Func<T, bool>> whereExpression)
        {
            return CurrentDb.Delete(whereExpression);
        }


        /// <summary>
        /// 执行sql
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public virtual int ExecuteSql(string sql, params SugarParameter[] parameters)
        {
            return Db.Ado.ExecuteCommand(sql, parameters);
        }

        /// <summary>
        /// 执行sql
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public virtual List<T> ExecuteSelectSql(string sql, params SugarParameter[] parameters)
        {
            return Db.Ado.SqlQuery<T>(sql, parameters);
        }


    }
}
